﻿#include "../../libcat/include/cat-module.hpp"
#include "../../libcat/include/util/json.h"
#include "../../libcat/include/util/jsoncpp.cpp"

#include <string>
#include <corecrt_io.h>
#include <vector>

#include <Mmsystem.h>
#include <mciapi.h>
//these two headers are already included in the <Windows.h> header
#pragma comment(lib, "Winmm.lib")

namespace {
	sf::Clock timer;
	sf::Clock timer2;

	long long count = 0;
	bool keys[256];
	int keyCountRecord[100];
	
	unsigned int kpsid = 0;
	int kps = 0;

	std::vector<std::wstring> soundName;

	static void GetSoundName(const char* filePath)
	{
		int wchars_num = MultiByteToWideChar(CP_UTF8, 0, filePath, -1, NULL, 0);
		wchar_t* wstr = new wchar_t[wchars_num];
		MultiByteToWideChar(CP_UTF8, 0, filePath, -1, wstr, wchars_num);
		
		std::wstring _filepath = wstr;
		_filepath += L"/*.mp3";
		
		struct _wfinddata64i32_t fileInfo;
		long long findResult = _wfindfirst(_filepath.c_str(), &fileInfo);
		if (findResult == -1) {
			_findclose(findResult);
			return;
		}

		do
		{
			std::wstring dllpath = std::wstring(wstr) + L"/" +fileInfo.name;
			soundName.push_back(dllpath);
		} while (_wfindnext(findResult, &fileInfo) == 0);

		_findclose(findResult);
		delete [] wstr;
	}
	DWORD WINAPI MP3Proc(_In_ LPVOID lpParameter)
	{
		while (true)
		{
			srand((unsigned)time(NULL));
			int no = rand()%(soundName.size()-1);
			std::wstring file = L"open \"";
			file += soundName[no];
			file += L"\" type mpegvideo alias mp3";
			mciSendStringW(file.c_str(), NULL, 0, NULL);
			mciSendStringW(L"play mp3 from 0 wait", NULL, 0, NULL);
			mciSendStringW(L"close mp3", NULL, 0, NULL);
			//Do here what you want to do when the mp3 playback is over
			SuspendThread(GetCurrentThread()); //or the handle of this thread that you keep in a static variable instead
		}
	}
}

const char* get_name() {
	return u8"彩虹屁";
}

void* Init(cat_data_t* settings) {
	soundName.clear();
	timer.restart();
	timer2.restart();
	count = 0;
	for (int i = 0; i < 256;i++) {
		keys[i] = false;
	}
	for (int i = 0; i < 100; i++) {
		keyCountRecord[i] = 0;
	}
	GetSoundName("data/voices"); 
	return settings;
}

static bool isactive = false;

void* Update(cat_data_t* settings) {
	for (auto entry = settings->json["plugins"]["module"].begin(); entry != settings->json["plugins"]["module"].end(); entry++)
	{
		if ((*entry)["module_id"].asInt() == -3) {
			if (isactive != (*entry)["active"].asBool()) {
				isactive=(*entry)["active"].asBool();
				if (isactive)
				{
					Init(settings);
				}
			}
			break;
		}
	}	
	return settings;
}

void* Release() {

	count = 0;

	return NULL;
};

void* Run(void* _window) {

	if (timer.getElapsedTime() > sf::seconds(0.2)) {
		timer.restart();
		if (kpsid > 100)
			kpsid = 0;

		keyCountRecord[kpsid] = count;

		if (kpsid < 5) {
			kps = keyCountRecord[kpsid] -
				keyCountRecord[100 - (5 - kpsid)];
		}
		else {
			kps = keyCountRecord[kpsid] - keyCountRecord[kpsid - 5];
		}
		kpsid++;
		if (kps < 0) {
			kps = 0;
		}
	}
	if (kps > 5 && timer2.getElapsedTime()>sf::seconds(5)) {
		timer2.restart();
		CreateThread(NULL, 0, MP3Proc, 0, 0, 0);
	}

	return _window;
};

void* OnMouseClick(const cat_mouse_click_event* event, bool key_up)
{
	if (!key_up)
		count++;
	return NULL;
}

void* OnKeyPress(const cat_key_event* event, bool key_up)
{
	if (!keys[event->native_vkey]) {
		keys[event->native_vkey] = !key_up;
		count++;
	}
	else {
		keys[event->native_vkey] = !key_up;
	}
	return NULL;
}

CAT_DECLARE_MODULE()
bool cat_module_load (){
	cat_source_info rinbow {};
	rinbow.id = -3;
	rinbow.type = CAT_SOURCE_TYPE_UI;
	rinbow.Init = Init;
	rinbow.Update = Update;
	rinbow.Release = Release;
	rinbow.Run = Run;
	rinbow.get_name = get_name;
	rinbow.OnMouseClick = OnMouseClick;
	rinbow.OnKeyPress = OnKeyPress;

	cat_register_source(&rinbow);
	return true;
}
